package shortcircuit;

import java.awt.*;
import java.awt.image.CropImageFilter;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageFilter;
import java.awt.image.ImageProducer;
import java.awt.image.RGBImageFilter;

import javax.swing.*;

import shortcircuit.basics.Cell;
import shortcircuit.basics.PowerUp;
import shortcircuit.graphics.PopUpScreen;

import java.util.ArrayList;

/**
 * This class serves as the main class for the Screens, or JFrames, that we will add to this 
 * specialized JFrame. The JFrame starts off by loading all of the images that will be
 * needed for our game and setting predetermined sizes for all of them, scaling as needed.
 * It contains an adjustable array of JPanels, which will be used to hold the screens that make
 * up each mode of the game and are separately controlled by Engines.
 * 
 * @author David Li
 */
public class Display extends JFrame{
	private JPanel _Panel = new JPanel();
	private ArrayList<JPanel> _Screens = new ArrayList<JPanel>();
	private JPanel powerUpPanel;
	private GameEngine _Engine;
	
	private ArrayList<PowerUp> thePowerUps = new ArrayList<PowerUp>();
	private ArrayList<Point> startCoords = new ArrayList<Point>();
	private ArrayList<Point> endCoords = new ArrayList<Point>();
	private ArrayList<Integer> powerUpSteps = new ArrayList<Integer>();
	
	private MediaTracker mediaTracker;
	public static Image[] imageBlock;
	public static Image beamImage;
	public static Image[] modeImages;
	public static Image[] numberImages;
	public static Image[] numberImagesSmall;
	public static Image levelImage;
	public static Image readyImage;
	public static Image goImage;
	public static Image puzzleModeImage;
	public static Image endlessModeImage;
	public static Image levelStatsImage;
	public static Image scoreStatsImage;
	public static Image levelCompleteImage;
	public static Image failureImage;
	public static Image gameOverImage;
	public static Image nextLevelImage;
	public static Image tryAgainImage;
	public static Image quitStatImage;
	public static Image quitEndImage;
	public static Image pauseImage;
	public static Image spotlightImage;
	public static Image cursorImage;
	public static Image titleImage;
	public static Image bgImage;
	public static Image blocksRemainingImage;
	public static Image movesLeftImage;
	public static Image[] powerUps;
	public static Image[] powerUpsSelected;
	public static Image powerUpsImage;
	public static Image chooseALevelImage;
	public static Image highScoreImage;
	public static Image howToPlayImage;
	public static Image demoImage;
	public static Image selectedBlockGlowImage;
	
	public static final int TOOLBAR_OFFSET = 15;
	
	public Display(GameEngine theEngine)
	{
		_Engine = theEngine;
		//_Panel.setOpaque(false);
		_Panel.setLayout(null);
		powerUpPanel = new JPanel();
		powerUpPanel.setOpaque(false);
		powerUpPanel.setLayout(null);
		setVisible(true);
		loadImages();
		setContentPane(_Panel);
		setResizable(false);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
	}
	
	public void addPowerUp(PowerUp thePowerUp)
	{
		Cell[][] theGrid = _Engine.getEnvironmentPane().getEnvironment().getGrid();
		Point cellPosition = new Point();
		for(int x = 0; x < theGrid.length; x++)
		{
			for(int y = 0; y < theGrid[x].length; y++)
			{
				if(thePowerUp == 
					_Engine.getEnvironmentPane().getEnvironment().getCell(x, y).getBlock().getPowerUp())
					cellPosition = new Point(x, y);
			}
		}
		thePowerUps.add(thePowerUp);
		startCoords.add(new Point(20 + cellPosition.x * 40, 420 - (cellPosition.y * 40)));
		endCoords.add(new Point(_Engine.statsScreen.powerupsLabels.get(0).getLocation().x + 240 + 75, _Engine.statsScreen.powerupsLabels.get(0).getLocation().y + 135));
		powerUpSteps.add(0);
	}
	
	public static Image getScaledImage(Image myImage, double scaleFactor)
	{
		int scaledX = (int) (scaleFactor * (double) myImage.getWidth(null));
		int scaledY = (int) (scaleFactor * (double) myImage.getHeight(null));
		return myImage.getScaledInstance(scaledX , scaledY, Image.SCALE_SMOOTH);
	}
	
	public void directlyAddScreen(JPanel theScreen, int zOrder)
	{
		_Panel.add(theScreen);
		_Panel.setComponentZOrder(theScreen, zOrder);
		_Panel.repaint();
	}		
	
	public void removeScreen(PopUpScreen theScreen)
	{
		if(theScreen.doneLoading && !theScreen.beginFading)
		{
			_Panel.remove(theScreen);
		}
	}
	
	public void addScreen(JPanel theScreen){
		int screenWidth = 0;
		_Screens.add(theScreen);
		_Panel.add(theScreen);
		try
		{
			_Panel.setComponentZOrder(theScreen, _Screens.size());
		}
		catch(IllegalArgumentException e)
		{
			_Panel.setComponentZOrder(theScreen, 0);
		}
		if(_Screens.size()>0){
			_Screens.get(0).setLocation(0, 0);
			screenWidth = _Screens.get(0).getWidth();
		}
		
		for(int x=1;x<_Screens.size();x++){
			_Screens.get(x).setLocation(_Screens.get(x-1).getLocation().x+_Screens.get(x-1).getWidth(),0);
			screenWidth += _Screens.get(x).getX();
		}
		screenWidth = 440;
		int screenHeight = _Screens.get(0).getHeight();
		setSize(440 + TOOLBAR_OFFSET, 420 + TOOLBAR_OFFSET);
	}
	
	public void clearScreens(){
		_Screens = new ArrayList<JPanel>();
		_Panel.removeAll();
	}
	
	/**
	 * Separately loads the images for later use.
	 * 
	 * @author Kevin Lewi
	 */
	private void loadImages()
	{
		Toolkit toolKit = this.getToolkit();
		
		MediaTracker initialMediaTracker = new MediaTracker(this);
		bgImage = toolKit.getImage("resources/bg.png");
		initialMediaTracker.addImage(bgImage, 0);
		try
		{
			initialMediaTracker.waitForAll();
		}
		catch(InterruptedException e) { System.out.println("Interrupted (Initial)"); }
		
		bgImage = bgImage.getScaledInstance(1000, 500, Image.SCALE_SMOOTH);
		
		int currentIndex = 0;
		mediaTracker = new MediaTracker(this);
		imageBlock = new Image[7];
		modeImages = new Image[5];
		for(int i = 0; i < imageBlock.length; i++)
		{
			imageBlock[i] = toolKit.getImage("resources/Block" + i + ".png");
			mediaTracker.addImage(imageBlock[i], i);
		}
		for(int i = 0; i < modeImages.length; i++)
		{
			modeImages[i] = toolKit.getImage("resources/modeImage" + i + ".png");
			mediaTracker.addImage(modeImages[i], i + imageBlock.length);
		}
		beamImage = toolKit.getImage("resources/Beam.jpg");
		mediaTracker.addImage(beamImage, imageBlock.length + modeImages.length);
		currentIndex = imageBlock.length + modeImages.length + 1;
		levelImage = toolKit.getImage("resources/levelImage.png");
		mediaTracker.addImage(levelImage, currentIndex);
		currentIndex++;
		scoreStatsImage = toolKit.getImage("resources/scoreImage.png");
		mediaTracker.addImage(scoreStatsImage, currentIndex);
		currentIndex++;
		readyImage = toolKit.getImage("resources/readyImage.png");
		mediaTracker.addImage(readyImage, currentIndex);
		currentIndex++;
		goImage = toolKit.getImage("resources/goImage.png");
		mediaTracker.addImage(goImage, currentIndex);
		currentIndex++;
		levelCompleteImage = toolKit.getImage("resources/levelCompleteImage.png");
		mediaTracker.addImage(levelCompleteImage, currentIndex);
		currentIndex++;
		failureImage = toolKit.getImage("resources/failureImage.png");
		mediaTracker.addImage(failureImage, currentIndex);
		currentIndex++;
		gameOverImage = toolKit.getImage("resources/gameOverImage.png");
		mediaTracker.addImage(gameOverImage, currentIndex);
		currentIndex++;
		nextLevelImage = toolKit.getImage("resources/nextLevelImage.png");
		mediaTracker.addImage(nextLevelImage, currentIndex);
		currentIndex++;
		tryAgainImage = toolKit.getImage("resources/tryAgainImage.png");
		mediaTracker.addImage(tryAgainImage, currentIndex);
		currentIndex++;
		pauseImage = toolKit.getImage("resources/pauseImage.png");
		mediaTracker.addImage(pauseImage, currentIndex);
		currentIndex++;
		quitStatImage = toolKit.getImage("resources/quitImage.png");
		mediaTracker.addImage(quitStatImage, currentIndex);
		currentIndex++;
		quitEndImage = toolKit.getImage("resources/quitImage.png");
		mediaTracker.addImage(quitEndImage, currentIndex);
		currentIndex++;
		spotlightImage = toolKit.getImage("resources/spotlight.png");
		mediaTracker.addImage(spotlightImage, currentIndex);
		currentIndex++;
		titleImage = toolKit.getImage("resources/titleImage.png");
		mediaTracker.addImage(titleImage, currentIndex);
		currentIndex++;
		blocksRemainingImage = toolKit.getImage("resources/blocksRemainingImage.png");
		mediaTracker.addImage(blocksRemainingImage, currentIndex);
		currentIndex++;
		movesLeftImage = toolKit.getImage("resources/movesLeftImage.png");
		mediaTracker.addImage(movesLeftImage, currentIndex);
		currentIndex++;
		powerUpsImage = toolKit.getImage("resources/powerUpsImage.png");
		mediaTracker.addImage(powerUpsImage, currentIndex);
		currentIndex++;
		highScoreImage = toolKit.getImage("resources/highScoreImage.png");
		mediaTracker.addImage(highScoreImage, currentIndex);
		currentIndex++;
		chooseALevelImage = toolKit.getImage("resources/chooseALevelImage.png");
		mediaTracker.addImage(chooseALevelImage, currentIndex);
		currentIndex++;
		howToPlayImage = toolKit.getImage("resources/howToPlayImage.png");
		mediaTracker.addImage(howToPlayImage, currentIndex);
		currentIndex++;
		demoImage = toolKit.getImage("resources/demoImage.png");
		mediaTracker.addImage(demoImage, currentIndex);
		currentIndex++;
		selectedBlockGlowImage = toolKit.getImage("resources/selectedBlockGlowImage.png");
		mediaTracker.addImage(selectedBlockGlowImage, currentIndex);
		currentIndex++;
		powerUps = new Image[1];
		for(int i = 0; i < powerUps.length; i++)
		{
			powerUps[i] = toolKit.getImage("resources/powerUp" + i + ".png");
			mediaTracker.addImage(powerUps[i], currentIndex);
			currentIndex++;
		}
		powerUpsSelected = new Image[1];
		for(int i = 0; i < powerUpsSelected.length; i++)
		{
			powerUpsSelected[i] = toolKit.getImage("resources/powerUp" + i + "_Selected.png");
			mediaTracker.addImage(powerUpsSelected[i], currentIndex);
			currentIndex++;
		}
		
		numberImages = new Image[10];
		for(int i = 0; i < numberImages.length; i++)
		{
			numberImages[i] = toolKit.getImage("resources/" + i + ".png");
			mediaTracker.addImage(numberImages[i], currentIndex);
			currentIndex++;
		}
		adjustImages();
		try
		{
			mediaTracker.waitForAll();
		}
		catch(InterruptedException e) {}
	}
	
	public void adjustImages()
	{
		howToPlayImage = howToPlayImage.getScaledInstance(180, 40, Image.SCALE_SMOOTH);
		chooseALevelImage = chooseALevelImage.getScaledInstance(300, 50, Image.SCALE_SMOOTH);
		highScoreImage = highScoreImage.getScaledInstance(110, 40, Image.SCALE_SMOOTH);
		movesLeftImage = movesLeftImage.getScaledInstance(100, 30, Image.SCALE_SMOOTH);
		powerUpsImage = powerUpsImage.getScaledInstance(110, 30, Image.SCALE_SMOOTH);
		blocksRemainingImage = blocksRemainingImage.getScaledInstance(120, 40, Image.SCALE_SMOOTH);
		titleImage = titleImage.getScaledInstance(400, 50, Image.SCALE_SMOOTH);
		quitStatImage = quitStatImage.getScaledInstance(60, 20, Image.SCALE_SMOOTH);
		quitEndImage = quitEndImage.getScaledInstance(30, 20, Image.SCALE_SMOOTH);
		pauseImage = pauseImage.getScaledInstance(80, 20, Image.SCALE_SMOOTH);
		nextLevelImage = nextLevelImage.getScaledInstance(70, 20, Image.SCALE_SMOOTH);
		tryAgainImage = tryAgainImage.getScaledInstance(70, 25, Image.SCALE_SMOOTH);
		levelCompleteImage = levelCompleteImage.getScaledInstance(120, 30, Image.SCALE_SMOOTH);
		failureImage = failureImage.getScaledInstance(100, 30, Image.SCALE_SMOOTH);
		gameOverImage = gameOverImage.getScaledInstance(100, 30, Image.SCALE_SMOOTH);
		levelImage = levelImage.getScaledInstance(90, 30, Image.SCALE_SMOOTH);
		puzzleModeImage	 = modeImages[0].getScaledInstance(160, 40, Image.SCALE_SMOOTH);
		endlessModeImage = modeImages[1].getScaledInstance(160, 40, Image.SCALE_SMOOTH);
		levelStatsImage = levelImage.getScaledInstance(75, 30, Image.SCALE_SMOOTH);
		scoreStatsImage = scoreStatsImage.getScaledInstance(75, 30, Image.SCALE_SMOOTH);
		readyImage = readyImage.getScaledInstance(110, 40, Image.SCALE_SMOOTH);
		goImage = goImage.getScaledInstance(50, 30, Image.SCALE_SMOOTH);
		numberImagesSmall = new Image[10];
		for(int i = 0; i < modeImages.length; i++)
		{
			modeImages[i] = modeImages[i].getScaledInstance(160, 30, Image.SCALE_SMOOTH);
		}
		for(int i = 0; i < numberImages.length; i++)
		{
			numberImagesSmall[i] = numberImages[i].getScaledInstance(15, 30, Image.SCALE_SMOOTH);
			numberImages[i] = numberImages[i].getScaledInstance(18, 36, Image.SCALE_SMOOTH);
		}
	}
	
	public static ArrayList<JLabel> generateLabels(int theNumber)
	{
		ArrayList<JLabel> theArray = new ArrayList<JLabel>();
		String s = new Integer(theNumber).toString();
		int stringLength = s.length();
		for(int i = 0; i < stringLength; i++)
		{
			theArray.add(new JLabel(new ImageIcon(
					Display.numberImagesSmall[Integer.parseInt(s.substring(0, 1))])));
			if(i != stringLength - 1)
				s = s.substring(1);
		}
		return theArray;
	}

	public static ArrayList<Image> generateImages(int theNumber)
	{
		ArrayList<Image> theArray = new ArrayList<Image>();
		String s = new Integer(theNumber).toString();
		int stringLength = s.length();
		for(int i = 0; i < stringLength; i++)
		{
			theArray.add(Display.numberImages[Integer.parseInt(s.substring(0, 1))]);
			if(i != stringLength - 1)
				s = s.substring(1);
		}
		return theArray;
	}
	
	private void stepPowerUps()
	{
		powerUpPanel.removeAll();
		for(int i = 0; i < thePowerUps.size(); i++)
		{
			powerUpPanel.add(new JLabel(new ImageIcon(thePowerUps.get(i).getImage())));
		}

	}

	/*
	private class AnimatePowerUps
	{
		public void run()
		{
			while(Thread.currentThread() == powerUpAnimator)
			{
				try
				{
					Thread.sleep(10);
				}
				catch(InterruptedException e) {}
				stepPowerUps();
			}
		}
	}*/
}
